package com.android.camera;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.MotionEvent;

@SuppressLint("DrawAllocation")
public class NavAnimationView extends View {
	private static final int HAND_TRANSLATE_RANGE = 160;
	private static final int VERTICAL_DISTANCE = 30;

	private int mWidth;
	private int mHeight;
	private int mHalfWidth;
	private int mHalfHeight;
	private Direction direction = Direction.NONE;

	public enum Direction {
		LEFT, TOP, RIGHT, BOTTOM, NONE;
	}

	private int navAlpha;
	private float handDegrees;
	private int handTranslate;
	private float rotate3Ddegrees;
	private float mNaviIconRotateDegrees;
	private int maxNaviIcon1Translate;
	private int maxNaviIcon2Translate;
	private int naviIcon1Translate;
	private int naviIcon2Translate;

	private float mFraction;

	private Rect mSrc = new Rect();
	private Rect mDst = new Rect();
	private ScaleInfo mScaleInfo = new ScaleInfo(60, 60, 60, 60);

	private Bitmap navIcon1;
	private Bitmap navIcon2;
	private Bitmap navIcon3;
	private Bitmap[] naviIcon;
	private Bitmap horizontalHandIcon;
	private Bitmap verticalHandIcon;
	private Bitmap leftArrowIcon;
	private Bitmap rightArrowIcon;
	private Bitmap upArrowIcon;
	private Bitmap downArrowIcon;
	private Bitmap frontBackCamIcon;

	private Paint mPaint;

	private ValueAnimator mToRightValueAnimator;
	private ValueAnimator mToLeftValueAnimator;
	private ValueAnimator mRepeatToLeftValueAnimator;
	private ValueAnimator mToTopValueAnimator;
	private ValueAnimator mToBottomValueAnimator;

	private ValueAnimator mLineValueAnimator;
	private int mLineAlpha = 0xFF;

	private AnimatorListener mAnimatorListener;

	public NavAnimationView(Context context) {
		this(context, null);
	}

	public NavAnimationView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public NavAnimationView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		Resources res = getResources();
		navIcon1 = BitmapFactory.decodeResource(res, R.drawable.nav_beauty);
		navIcon2 = BitmapFactory.decodeResource(res, R.drawable.nav_photo);
		navIcon3 = BitmapFactory.decodeResource(res, R.drawable.nav_video);
		horizontalHandIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_hand_horizontal);
		verticalHandIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_hand_vertical);
		leftArrowIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_line_arrow_left);
		rightArrowIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_line_arrow_right);
		upArrowIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_line_arrow_up);
		downArrowIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_line_arrow_down);
		frontBackCamIcon = BitmapFactory.decodeResource(res,
				R.drawable.nav_cam_front_back);

		naviIcon = new Bitmap[2];

		mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

		initAnimators();
	}

	private void initAnimators() {
		mSrc.left = 0;
		mSrc.right = navIcon1.getWidth();
		mSrc.top = 0;
		mSrc.bottom = navIcon1.getHeight();

		mLineValueAnimator = ValueAnimator.ofFloat(1, 0);
		mLineValueAnimator.setDuration(300);
		mLineValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				mLineAlpha = 0xFF;
				if (direction == Direction.RIGHT) {
					direction = Direction.LEFT;
					naviIcon[0] = navIcon1;
					naviIcon[1] = navIcon2;
					calculateNextMaxNaviIconTranslate();
					mToLeftValueAnimator.start();
				} else if (direction == Direction.LEFT) {
					direction = Direction.TOP;
					mToTopValueAnimator.start();
				}
			}
		});
		mLineValueAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator anim) {
				float fraction = (Float) anim.getAnimatedValue();
				mLineAlpha = (int) (0xFF * fraction);
				invalidate(); // to re draw ui
			}
		});

		mToRightValueAnimator = ValueAnimator.ofFloat(0, 1);
		mToRightValueAnimator.setDuration(1000);
		mToRightValueAnimator
				.setInterpolator(new AccelerateDecelerateInterpolator());
		mToRightValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				// direction = Direction.LEFT;
				// mToLeftValueAnimator.start();
				mLineValueAnimator.start();
			}

		});
		mToRightValueAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator anim) {
				float fraction = (Float) anim.getAnimatedValue();
				mFraction = fraction;
				naviIcon1Translate = (int) (maxNaviIcon1Translate * fraction);
				naviIcon2Translate = (int) (maxNaviIcon2Translate * fraction);
				mNaviIconRotateDegrees = 5 * fraction - 5;
				int halfW = navIcon1.getWidth() >> 1;
				mScaleInfo.leftWidth = mScaleInfo.leftHeight = (int) (halfW
						* fraction + halfW);
				mScaleInfo.rightWidth = mScaleInfo.rightHeight = (int) (halfW
						* (1 - fraction) + halfW);
				navAlpha = (int) (0xFF * fraction);
				handDegrees = 40 * fraction - 20;
				handTranslate = (int) (HAND_TRANSLATE_RANGE * fraction - (HAND_TRANSLATE_RANGE >> 1));
				invalidate(); // to re draw ui
			}
		});

		mToLeftValueAnimator = ValueAnimator.ofFloat(1, 0);
		mToLeftValueAnimator.setDuration(1000);
		mToLeftValueAnimator
				.setInterpolator(new AccelerateDecelerateInterpolator());
		mToLeftValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				// direction = Direction.TOP;
				// mToTopValueAnimator.start();
				direction = Direction.LEFT;
				naviIcon[0] = navIcon2;
				naviIcon[1] = navIcon3;
				calculateNextMaxNaviIconTranslate();
				mRepeatToLeftValueAnimator.start();
			}
		});
		mToLeftValueAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator anim) {
				float fraction = (Float) anim.getAnimatedValue();
				mFraction = fraction;
				naviIcon1Translate = (int) (maxNaviIcon1Translate * fraction)
						- maxNaviIcon1Translate;
				naviIcon2Translate = (int) (maxNaviIcon2Translate * fraction)
						- maxNaviIcon2Translate;
				mNaviIconRotateDegrees = 5 * fraction - 5;
				int halfW = navIcon1.getWidth() >> 1;
				mScaleInfo.leftWidth = mScaleInfo.leftHeight = (int) (halfW
						* fraction + halfW);
				mScaleInfo.rightWidth = mScaleInfo.rightHeight = (int) (halfW
						* (1 - fraction) + halfW);
				navAlpha = (int) (0xFF * fraction);
				handDegrees = 40 * fraction - 20;
				handTranslate = (int) (HAND_TRANSLATE_RANGE * fraction - (HAND_TRANSLATE_RANGE >> 1));
				invalidate(); // to re draw ui
			}
		});

		mRepeatToLeftValueAnimator = ValueAnimator.ofFloat(1, 0);
		mRepeatToLeftValueAnimator.setDuration(1000);
		mRepeatToLeftValueAnimator
				.setInterpolator(new AccelerateDecelerateInterpolator());
		mRepeatToLeftValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				// direction = Direction.TOP;
				// mToTopValueAnimator.start();
				mLineValueAnimator.start();
			}
		});
		mRepeatToLeftValueAnimator
				.addUpdateListener(new AnimatorUpdateListener() {

					@Override
					public void onAnimationUpdate(ValueAnimator anim) {
						float fraction = (Float) anim.getAnimatedValue();
						mFraction = fraction;
						naviIcon1Translate = (int) (maxNaviIcon1Translate * fraction)
								- maxNaviIcon1Translate;
						naviIcon2Translate = (int) (maxNaviIcon2Translate * fraction)
								- maxNaviIcon2Translate;
						mNaviIconRotateDegrees = 5 * fraction - 5;
						int halfW = navIcon1.getWidth() >> 1;
						mScaleInfo.leftWidth = mScaleInfo.leftHeight = (int) (halfW
								* fraction + halfW);
						mScaleInfo.rightWidth = mScaleInfo.rightHeight = (int) (halfW
								* (1 - fraction) + halfW);
						navAlpha = (int) (0xFF * fraction);
						handDegrees = 40 * fraction - 20;
						handTranslate = (int) (HAND_TRANSLATE_RANGE * fraction - (HAND_TRANSLATE_RANGE >> 1));
						invalidate(); // to re draw ui
					}
				});

		mToTopValueAnimator = ValueAnimator.ofFloat(0, 1);
		mToTopValueAnimator.setDuration(1000);
		mToTopValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				direction = Direction.BOTTOM;
				mToBottomValueAnimator.start();
			}
		});
		mToTopValueAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator anim) {
				float fraction = (Float) anim.getAnimatedValue();
				mFraction = fraction;
				rotate3Ddegrees = 180 * fraction;
				Log.d("sqm", "mToTopValueAnimator---rotate3Ddegrees="
						+ rotate3Ddegrees);
				if (rotate3Ddegrees >= 88 && rotate3Ddegrees <= 92) {
					rotate3Ddegrees += 5;
				}
				navAlpha = (int) (0xFF * fraction);
				handDegrees = 40 * fraction - 20;
				handTranslate = (int) ((HAND_TRANSLATE_RANGE >> 1) - HAND_TRANSLATE_RANGE
						* fraction);
				invalidate(); // to re draw ui
			}
		});

		mToBottomValueAnimator = ValueAnimator.ofFloat(1, 0);
		mToBottomValueAnimator.setDuration(1000);
		mToBottomValueAnimator.addListener(new AnimatorListenerAdapter() {

			@Override
			public void onAnimationEnd(Animator animation) {
				super.onAnimationEnd(animation);
				if (mAnimatorListener != null) {
					mAnimatorListener.onAnimationEnd();
				}
			}
		});
		mToBottomValueAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator anim) {
				float fraction = (Float) anim.getAnimatedValue();
				mFraction = fraction;

				rotate3Ddegrees = 180 * fraction;
				if (rotate3Ddegrees >= 88 && rotate3Ddegrees <= 92) {
					rotate3Ddegrees += 5;
				}
				navAlpha = (int) (0xFF * fraction);
				handDegrees = 40 * fraction - 20;
				handTranslate = (int) ((HAND_TRANSLATE_RANGE >> 1) - HAND_TRANSLATE_RANGE
						* fraction);
				invalidate(); // to re draw ui
			}
		});
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		return true;
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		int heightSize = MeasureSpec.getSize(heightMeasureSpec);

		if (widthMode != MeasureSpec.EXACTLY
				|| heightMode != MeasureSpec.EXACTLY) {
			throw new IllegalArgumentException("mode must MeasureSpec.EXACTLY!");
		}
		Log.d("sqm", "NavAnimationView[onMeasure]---widthSize=" + widthSize
				+ ", heightSize=" + heightSize);

		mWidth = widthSize;
		mHeight = heightSize;

		mHalfWidth = mWidth >> 1;
		mHalfHeight = mHeight >> 1;

		setMeasuredDimension(mWidth, mHeight);

		// startAnimation();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Log.d("sqm", "onDraw start...");
		if (direction == Direction.NONE) {
			return;
		}

		Bitmap bm = getMiddleStaticIcon();
		int staticIconW = bm.getWidth();
		int staticIconH = bm.getHeight();
		int left = (mWidth - staticIconW) >> 1;
		int top = (mHeight - staticIconH) >> 1;
		mPaint.setAlpha(mLineAlpha);
		canvas.drawBitmap(bm, left, top, mPaint);

		if (direction == Direction.LEFT || direction == Direction.RIGHT) {
			String text = getContext().getString(R.string.navi_text_1);
			drawText(canvas, text, top - navIcon1.getHeight() - 50);
		} else if (direction == Direction.TOP || direction == Direction.BOTTOM) {
			String text = getContext().getString(R.string.navi_text_2);
			drawText(canvas, text, top - 50);
		}

		int oriLeft;
		int oriTop = top - navIcon1.getHeight() - 20;
		Bitmap rotated3Dbmp;
		int centerX;
		int centerY;
		int verticalTranslate;

		mPaint.reset();
		mPaint.setAntiAlias(true);
		mPaint.setFilterBitmap(true);

		switch (direction) {
		case NONE:
			break;

		case LEFT:
			Log.d("sqm", "left---");

			oriLeft = (mWidth - naviIcon[0].getWidth()) >> 1;
			verticalTranslate = (int) (VERTICAL_DISTANCE - VERTICAL_DISTANCE
					* mFraction);
			drawNaviIcon1(canvas, naviIcon[0], oriLeft, oriTop,
					mScaleInfo.leftWidth, mScaleInfo.leftHeight,
					naviIcon1Translate, verticalTranslate,
					mNaviIconRotateDegrees, navAlpha);

			oriLeft = left + staticIconW - naviIcon[1].getWidth();
			verticalTranslate = (int) (VERTICAL_DISTANCE * mFraction);
			drawNaviIcon1(canvas, naviIcon[1], oriLeft, oriTop,
					mScaleInfo.rightWidth, mScaleInfo.rightHeight,
					naviIcon2Translate, verticalTranslate,
					mNaviIconRotateDegrees + 5, 0xFF - navAlpha);

			oriLeft = (mWidth - horizontalHandIcon.getWidth()) >> 1;
			oriTop = top + staticIconH;
			drawHorizontalHandIcon1(canvas, horizontalHandIcon, oriLeft,
					oriTop, handTranslate, handDegrees, mLineAlpha);
			break;

		case RIGHT:
			Log.d("sqm", "right---navAlpha=" + navAlpha);

			oriLeft = left;
			verticalTranslate = (int) (VERTICAL_DISTANCE - VERTICAL_DISTANCE
					* mFraction);
			drawNaviIcon1(canvas, naviIcon[0], oriLeft, oriTop,
					mScaleInfo.leftWidth, mScaleInfo.leftHeight,
					naviIcon1Translate, verticalTranslate,
					mNaviIconRotateDegrees, navAlpha);

			oriLeft = (mWidth - navIcon2.getWidth()) >> 1;
			verticalTranslate = (int) (VERTICAL_DISTANCE * mFraction);
			drawNaviIcon1(canvas, naviIcon[1], oriLeft, oriTop,
					mScaleInfo.rightWidth, mScaleInfo.rightHeight,
					naviIcon2Translate, verticalTranslate,
					mNaviIconRotateDegrees + 5, 0xFF - navAlpha);

			oriLeft = (mWidth - horizontalHandIcon.getWidth()) >> 1;
			oriTop = top + staticIconH;
			drawHorizontalHandIcon1(canvas, horizontalHandIcon, oriLeft,
					oriTop, handTranslate, handDegrees, 0xFF);
			break;

		case TOP:
			Log.d("sqm", "top---navAlpha=" + navAlpha);

			centerX = mHalfWidth - ((frontBackCamIcon.getWidth() >> 1) + 30);
			centerY = mHalfHeight;
			rotated3Dbmp = rotate3DBitmap(frontBackCamIcon, rotate3Ddegrees,
					centerX, centerY);
			canvas.drawBitmap(rotated3Dbmp, centerX
					- (rotated3Dbmp.getWidth() >> 1),
					centerY - (rotated3Dbmp.getHeight() >> 1), mPaint);

			oriLeft = left + staticIconW;
			oriTop = (mHeight - verticalHandIcon.getHeight()) >> 1;
			drawVerticalHandIcon1(canvas, verticalHandIcon, oriLeft, oriTop,
					handTranslate, handDegrees, 0xFF);
			break;
		case BOTTOM:
			Log.d("sqm", "bottom---navAlpha=" + navAlpha);

			centerX = mHalfWidth - ((frontBackCamIcon.getWidth() >> 1) + 30);
			centerY = mHalfHeight;
			rotated3Dbmp = rotate3DBitmap(frontBackCamIcon, rotate3Ddegrees,
					centerX, centerY);
			canvas.drawBitmap(rotated3Dbmp, centerX
					- (rotated3Dbmp.getWidth() >> 1),
					centerY - (rotated3Dbmp.getHeight() >> 1), mPaint);

			oriLeft = left + staticIconW;
			oriTop = (mHeight - verticalHandIcon.getHeight()) >> 1;
			drawVerticalHandIcon1(canvas, verticalHandIcon, oriLeft, oriTop,
					handTranslate, handDegrees, 0xFF);
			break;
		}

		Log.d("sqm", "onDraw end.");
	}

	private void drawText(Canvas canvas, String text, int oriTop) {
		mPaint.setTextSize(25);
		mPaint.setColor(0xAFFFFFFF);
		float textWidth = mPaint.measureText(text);
		FontMetrics f = mPaint.getFontMetrics();
		float textHeight = f.descent - f.ascent;
		float startX = (mWidth - textWidth) / 2;
		float startY = oriTop - textHeight;
		canvas.drawText(text, startX, startY, mPaint);
	}

	private void drawNaviIcon(Canvas canvas, Bitmap naviIcon, int oriLeft,
			int oriTop, int width, int height, int translate,
			float rotateDegrees, int alpha) {
		Rect src = new Rect();
		Rect dst = new Rect();
		dst.left = ((naviIcon.getWidth() - width) >> 1) + oriLeft + translate;
		dst.right = width + dst.left;
		dst.top = ((naviIcon.getHeight() - height)) + oriTop;
		dst.bottom = dst.top + height;

		Bitmap scaledBmp = scaleBitmap(naviIcon, width, height);
		Bitmap rotatedBmp = rotateBitmap(scaledBmp, rotateDegrees);
		mDst.left = dst.centerX() - (rotatedBmp.getWidth() >> 1);
		mDst.right = dst.centerX() + (rotatedBmp.getWidth() >> 1);
		mDst.top = dst.centerY() - (rotatedBmp.getHeight() >> 1);
		mDst.bottom = dst.centerY() + (rotatedBmp.getHeight() >> 1);
		src.left = 0;
		src.right = rotatedBmp.getWidth();
		src.top = 0;
		src.bottom = rotatedBmp.getHeight();
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(rotatedBmp, src, mDst, mPaint);
	}

	private void drawNaviIcon1(Canvas canvas, Bitmap naviIcon, int oriLeft,
			int oriTop, int width, int height, int translate,
			int verticalTranslate, float rotateDegrees, int alpha) {
		canvas.save();
		int naviIconW = naviIcon.getWidth();
		int naviIconH = naviIcon.getHeight();
		canvas.translate(oriLeft + (naviIconW >> 1) + translate, oriTop
				+ (naviIconH >> 1) + verticalTranslate);
		canvas.rotate(rotateDegrees);
		canvas.translate(-(width >> 1), -(height >> 1));
		Rect src = new Rect(0, 0, naviIconW, naviIconH);
		Rect dst = new Rect(0, 0, width, height);
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(naviIcon, src, dst, mPaint);
		canvas.restore();
	}

	private void drawHorizontalHandIcon(Canvas canvas, Bitmap icon,
			int oriLeft, int oriTop, int translate, float rotateDegrees,
			int alpha) {
		Rect dst = new Rect();
		dst.left = oriLeft + translate;
		dst.right = dst.left + icon.getWidth();
		dst.top = oriTop;
		dst.bottom = dst.top + icon.getHeight();
		Bitmap handBmp = rotateBitmap(icon, rotateDegrees);
		oriLeft = dst.centerX() - (handBmp.getWidth() >> 1);
		oriTop = dst.centerY() - (handBmp.getHeight() >> 1);
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(handBmp, oriLeft, oriTop, mPaint);
	}

	private void drawHorizontalHandIcon1(Canvas canvas, Bitmap icon,
			int oriLeft, int oriTop, int translate, float rotateDegrees,
			int alpha) {
		canvas.save();
		int halfW = icon.getWidth() >> 1;
		int halfH = icon.getHeight() >> 1;
		canvas.translate(oriLeft + translate + halfW, oriTop + halfH);
		canvas.rotate(rotateDegrees);
		canvas.translate(-halfW, -halfH);
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(icon, 0, 0, mPaint);
		canvas.restore();
	}

	private void drawVerticalHandIcon(Canvas canvas, Bitmap icon, int oriLeft,
			int oriTop, int translate, float rotateDegrees, int alpha) {
		Rect dst = new Rect();
		dst.left = oriLeft;
		dst.right = dst.left + icon.getWidth();
		dst.top = oriTop + translate;
		dst.bottom = dst.top + icon.getHeight();
		Bitmap handBmp = rotateBitmap(icon, rotateDegrees);
		oriLeft = dst.centerX() - (handBmp.getWidth() >> 1);
		oriTop = dst.centerY() - (handBmp.getHeight() >> 1);
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(handBmp, oriLeft, oriTop, mPaint);
	}

	private void drawVerticalHandIcon1(Canvas canvas, Bitmap icon, int oriLeft,
			int oriTop, int translate, float rotateDegrees, int alpha) {
		canvas.save();
		int halfW = icon.getWidth() >> 1;
		int halfH = icon.getHeight() >> 1;
		canvas.translate(oriLeft + halfW, oriTop + translate + halfH);
		canvas.rotate(rotateDegrees);
		canvas.translate(-halfW, -halfH);
		mPaint.setAlpha(alpha);
		canvas.drawBitmap(icon, 0, 0, mPaint);
		canvas.restore();
	}

	private Bitmap rotateBitmap(Bitmap bitmap, float degrees) {
		Log.d("sqm", "rotateBitmap start.");
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		Matrix matrix = new Matrix();
		matrix.postRotate(degrees);
		Bitmap rotateBmp = Bitmap
				.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		Log.d("sqm", "rotateBitmap end.");
		return rotateBmp;
	}

	// scale bitmap
	private Bitmap scaleBitmap(Bitmap bm, int w, int h) {
		Bitmap b = bm;
		int width = b.getWidth();
		int height = b.getHeight();
		// Log.d("sqm", "width=" + width + ", height=" + height);
		float scaleW = w * 1.0f / width;
		float scaleH = h * 1.0f / height;

		Matrix m = new Matrix();
		m.postScale(scaleW, scaleH);
		Bitmap bmp = Bitmap.createBitmap(b, 0, 0, width, height, m, true);
		// Log.d("sqm", "bb:width=" + bb.getWidth() + ", height=" +
		// bb.getHeight());
		return bmp;
	}

	private Bitmap rotate3DBitmap(Bitmap bitmap, float degrees, int centerX,
			int centerY) {
		Log.d("sqm", "rotate3DBitmap start.");
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();

		Camera cam = new Camera();
		Matrix matrix = new Matrix();
		cam.save();
		cam.rotateX(degrees);
		cam.getMatrix(matrix);
		cam.restore();
		matrix.preTranslate(-centerX, -centerY);
		matrix.postTranslate(centerX, centerY);
		Bitmap rotateBmp = Bitmap
				.createBitmap(bitmap, 0, 0, w, h, matrix, true);
		Log.d("sqm", "rotate3DBitmap end.");
		return rotateBmp;
	}

	private Bitmap getMiddleStaticIcon() {
		switch (direction) {
		case LEFT:
			return leftArrowIcon;
		case RIGHT:
			return rightArrowIcon;
		case TOP:
			return upArrowIcon;
		case BOTTOM:
			return downArrowIcon;
		}
		return null;
	}

	public void startAnimation() {
		// initAnimators();
		direction = Direction.RIGHT;
		naviIcon[0] = navIcon1;
		naviIcon[1] = navIcon2;
		calculateNextMaxNaviIconTranslate();
		mToRightValueAnimator.start();
	}

	public void stopAnimation() {
		direction = Direction.NONE;
	}

	private void calculateNextMaxNaviIconTranslate() {
		Bitmap bmp = getMiddleStaticIcon();
		maxNaviIcon1Translate = (bmp.getWidth() - naviIcon[0].getWidth()) >> 1;
		maxNaviIcon2Translate = (bmp.getWidth() - naviIcon[1].getWidth()) >> 1;
	}

	class ScaleInfo {
		int leftWidth;
		int rightWidth;
		int leftHeight;
		int rightHeight;

		public ScaleInfo() {

		}

		public ScaleInfo(int leftWidth, int rightWidth, int leftHeight,
				int rightHeight) {
			this.leftWidth = leftWidth;
			this.leftHeight = leftHeight;
			this.rightWidth = rightWidth;
			this.rightHeight = rightHeight;
		}
	}

	public void setAnimatorListener(AnimatorListener listener) {
		mAnimatorListener = listener;
	}

	interface AnimatorListener {
		void onAnimationEnd();
	}
}
